package com.mack.batterypicture.slice;

import com.mack.batterypicture.ResourceTable;
import com.mack.batterypicture.utils.Const;
import com.mack.batterypicture.utils.LogUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityConnection;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.bundle.ElementName;
import ohos.event.commonevent.*;
import ohos.rpc.*;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 分布式充电动画
 */
public class BatteryPictureAbilitySlice extends AbilitySlice {
    private static final String TAG = Const.TAG + BatteryPictureAbilitySlice.class.getSimpleName();

    private IRemoteObject remoteObject;

    private MathRemoteProxy proxy;

    private Context context;

    private MyCommonEventSubscriber subscriber;

    private boolean isLocal;

    // 计时器，默认获取电量传输
    private Timer timer;
    private TimerTask timerTask;

    private DirectionalLayout layout1;
    private DirectionalLayout layout2;

    private RoundProgressBar progressbar1;
    private RoundProgressBar progressbar2;

    private int progress_value1 = 0;
    private int progress_value2 = 100;

    private Button btnStart;
    private Button btnReverse;
    private Button btnStop;

    private int flag = 0;// 0结束， 1开始
    private int reverse = 1;// 1正向，0反向

    @Override
    public void onStart(Intent intent) {
        LogUtil.info(TAG, "onStart");
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_batterypicture);
        initConnectDevice(intent);
        initView();
        subscribe();
    }

    private void initView() {
        layout1 = (DirectionalLayout) findComponentById(ResourceTable.Id_layout1);
        layout2 = (DirectionalLayout) findComponentById(ResourceTable.Id_layout2);

        progressbar1 = (RoundProgressBar) findComponentById(ResourceTable.Id_progressbar1);
        progressbar2 = (RoundProgressBar) findComponentById(ResourceTable.Id_progressbar2);

        btnStart = (Button) findComponentById(ResourceTable.Id_btn_start);
        btnReverse = (Button) findComponentById(ResourceTable.Id_btn_reverse);
        btnStop = (Button) findComponentById(ResourceTable.Id_btn_stop);

        btnStart.setClickedListener(new ButtonClick());
        btnReverse.setClickedListener(new ButtonClick());
        btnStop.setClickedListener(new ButtonClick());

        showCharging();
    }

    // 开始充电
    private void startCharging(int pReverse) {
        reverse = pReverse;
        if(reverse == 1){
            progress_value1 = 0;
            progress_value2 = 100;
        }else{
            progress_value2 = 0;
            progress_value1 = 100;
        }
        stopCharging();
        if (timer == null) {
            timer = new Timer();
        }
        if (timerTask == null) {
            timerTask = new TimerTask() {
                @Override
                public void run() {
                    if(reverse==1){
                        progress_value1 = progress_value1 + 10;
                        progress_value2 = progress_value2 - 10;
                    }else{
                        progress_value2 = progress_value2 + 10;
                        progress_value1 = progress_value1 - 10;
                    }
                    showCharging();
                    flag = 1;
                    sendDataToRemote();
                    if (progress_value1 >= 100 || progress_value2 >= 100 || progress_value1 <=0 || progress_value2<=0 ) {
                        stopCharging();
                        flag = 0;
                        sendDataToRemote();
                        // showProgressBarValue();
                    }
                }
            };
        }
        timer.schedule(timerTask, 0, 1000);
    }

    private void showCharging() {
        //在主线程运行
        getUITaskDispatcher().asyncDispatch(new Runnable() {
            @Override
            public void run() {
                showProgressBarValue();
            }
        });
    }

    // 显示充电进度值
    private void showProgressBarValue(){
        if(isLocal){
            layout1.setVisibility(Component.VISIBLE);
            progressbar1.setProgressValue(progress_value1);
            progressbar1.setProgressHintText(progress_value1+"%");
            setProgressBarBackgroundColor(progressbar1, progress_value1);
            layout2.setVisibility(Component.HIDE);
            progressbar2.setVisibility(Component.HIDE);
            if(progress_value1>=100){
                btnStart.setVisibility(Component.HIDE);
                btnReverse.setVisibility(Component.VISIBLE);
            }else{
                btnStart.setVisibility(Component.VISIBLE);
                btnReverse.setVisibility(Component.HIDE);
            }
        }else{
            layout2.setVisibility(Component.VISIBLE);
            progressbar2.setProgressValue(progress_value2);
            progressbar2.setProgressHintText(progress_value2+"%");

            setProgressBarBackgroundColor(progressbar2, progress_value2);

            layout1.setVisibility(Component.HIDE);
            progressbar1.setVisibility(Component.HIDE);

            if(progress_value2>=100){
                btnStart.setVisibility(Component.HIDE);
                btnReverse.setVisibility(Component.VISIBLE);
            }else{
                btnStart.setVisibility(Component.VISIBLE);
                btnReverse.setVisibility(Component.HIDE);
            }
        }
    }

    // 根据电量设置进度条背景色
    private void setProgressBarBackgroundColor(ProgressBar progressbar, int value){
        if(null != progressbar){
            try {
                // 设置电量为红色
                if(value < 20) {
                    progressbar.setProgressColor(Color.RED);
                }else if(value > 70 ){
                    // 电量70%时，显示绿色
                    progressbar.setProgressColor(Color.GREEN);
                }else{
                    //20~70之间显示黄色
                    progressbar.setProgressColor(Color.YELLOW);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void stopCharging() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        if (timerTask != null) {
            timerTask.cancel();
            timerTask = null;
        }
    }

    private class ButtonClick implements Component.ClickedListener {
        @Override
        public void onClick(Component component) {
            int btnId = component.getId();
            switch (btnId) {
                case ResourceTable.Id_btn_start:
                    if(isLocal){
                        startCharging(1);
                    }else{
                        startCharging(0);
                    }
                    break;
                case ResourceTable.Id_btn_reverse:
                    if(isLocal){
                        startCharging(0);
                    }else{
                        startCharging(1);
                    }
                    break;
                case ResourceTable.Id_btn_stop:
                    stopCharging();
                    break;
                default:
                    break;
            }
        }
    }

    private void sendDataToRemote() {
        if (remoteObject != null && proxy != null) {
            try {
                LogUtil.info(TAG, "sendDataToRemote ---------");
                proxy.sendDataToRemote(MathRemoteProxy.REQUEST_SEND_DATA);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * connect the device
     */
    private void initConnectDevice(Intent intent) {
        context = BatteryPictureAbilitySlice.this;
        String remoteDeviceId = intent.getStringParam(Const.KEY_REMOTE_DEVICEID);
        isLocal = intent.getBooleanParam(Const.KEY_IS_LOCAL, false);
        if (findComponentById(ResourceTable.Id_title) instanceof Text) {
            Text textTitle = (Text) findComponentById(ResourceTable.Id_title);
            textTitle.setText(isLocal ? "（本地端）" : "（远程端）");
        }
        // Connect to remote service
        if (!remoteDeviceId.isEmpty()) {
            connectRemotePa(remoteDeviceId);
        } else {
            LogUtil.info(TAG, "localDeviceId is null");
        }
    }

    private void connectRemotePa(String deviceId) {
        if (!deviceId.isEmpty()) {
            Intent connectPaIntent = new Intent();
            Operation operation = new Intent.OperationBuilder().withDeviceId(deviceId)
                    .withBundleName(getBundleName())
                    .withAbilityName(Const.PACKAGE_SERVICE_NAME)
                    .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
                    .build();
            connectPaIntent.setOperation(operation);

            IAbilityConnection conn = new IAbilityConnection() {
                @Override
                public void onAbilityConnectDone(ElementName elementName, IRemoteObject remote, int resultCode) {
                    connectAbility(elementName, remote, resultCode);
                }
                @Override
                public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
                    disconnectAbility(this);
                }
            };

            context.connectAbility(connectPaIntent, conn);
        }
    }

    private void connectAbility(ElementName elementName, IRemoteObject remote, int resultCode) {
        remoteObject = remote;
        proxy = new MathRemoteProxy(remote);
        LogUtil.info(TAG, "connectRemoteAbility sucess ");
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribe();
        stopCharging();
    }

    // 订阅消息
    private void subscribe() {
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(Const.CHARGING_EVENT);
        matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_SCREEN_ON);
        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        subscriber = new MyCommonEventSubscriber(subscribeInfo);
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            LogUtil.error(TAG, "subscribeCommonEvent occur exception.");
        }
    }

    private void unSubscribe() {
        try {
            CommonEventManager.unsubscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            LogUtil.error(TAG, "unSubscribe Exception");
        }
    }

    /**
     * Establish a remote connection
     */
    class MathRemoteProxy implements IRemoteBroker {
        private static final int ERR_OK = 0;
        private static final int REQUEST_SEND_DATA = 1;
        private final IRemoteObject remote;
        MathRemoteProxy(IRemoteObject remote) {
            this.remote = remote;
        }
        @Override
        public IRemoteObject asObject() {
            return remote;
        }
        private synchronized void sendDataToRemote(int requestType) throws RemoteException {
            MessageParcel data = MessageParcel.obtain();
            MessageParcel reply = MessageParcel.obtain();
            MessageOption option = new MessageOption(MessageOption.TF_SYNC);
            try {
                data.writeInt(flag);
                remote.sendRequest(requestType, data, reply, option);

                if(isLocal){
                    data.writeInt(progress_value2);
                }else{
                    data.writeInt(progress_value1);
                }

                remote.sendRequest(requestType, data, reply, option);
                int ec = reply.readInt();
                if (ec != ERR_OK) {
                    LogUtil.error(TAG, "RemoteException:");
                }
            } catch (RemoteException e) {
                LogUtil.error(TAG, "RemoteException:");
            } finally {
                data.reclaim();
                reply.reclaim();
            }
        }
    }

    /**
     * 接收订阅消息
     */
    class MyCommonEventSubscriber extends CommonEventSubscriber {
        MyCommonEventSubscriber(CommonEventSubscribeInfo info) {
            super(info);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            Intent intent = commonEventData.getIntent();
            int flag = intent.getIntParam(Const.FLAG, 0);
            if(isLocal){
                progress_value1 = intent.getIntParam(Const.REMOTE_VALUE, 0);
            }else{
                progress_value2 = intent.getIntParam(Const.REMOTE_VALUE, 0);
            }
            LogUtil.error(TAG, "progress_value1:"+progress_value1+"; progress_value2:"+progress_value2);
            if (flag == 1) {
                showCharging();
            }else if(flag == 0){
                stopCharging();
            }
        }
    }
}
